package com.dingding.order.core.pay.biz.impl;

import java.math.BigDecimal;
import java.util.Date;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.daox.IBaseDaoX;
import com.dingding.common.core.base.dto.AbstractResponse;
import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.Useraccount;
import com.dingding.common.core.beans.special.Specialuserlogin;
import com.dingding.common.core.beans.special.Userspecialorder;
import com.dingding.common.core.beans.special.UserspecialorderT;
import com.dingding.common.core.model.push.PushModel;
import com.dingding.common.core.push.pushmsg.PushData;
import com.dingding.common.core.push.pushmsg.PushMsg;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.MD5Util;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.common.core.util.tools.wechat.WechatTool;
import com.dingding.common.core.util.tools.wechat.pay.WechatPayApi;
import com.dingding.common.core.util.tools.wechat.pay.WechatPayReqFactory;
import com.dingding.common.core.util.tools.wechat.pay.paybean.SecondSign;
import com.dingding.common.core.util.tools.wechat.pay.paybean.WechatPayOrderResponse;
import com.dingding.common.core.util.tools.wechat.pay.paybean.request.WechatPayOrderRequest;
import com.dingding.facade.account.user.service.IUserAccountService;
import com.dingding.facade.queue.dto.push.PushRequestDTO;
import com.dingding.facade.queue.enums.ClientType;
import com.dingding.facade.queue.enums.PushType;
import com.dingding.facade.queue.enums.RoleType;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.order.code.OrderPayCodeMsg;
import com.dingding.order.core.pay.biz.IOrderPayService;
import com.dingding.order.core.pay.dao.IOrderPayDao;
import com.dingding.order.core.pay.dto.SpecialOrderPayPushDto;
import com.dingding.order.core.special.biz.ISpecialOrderService;
import com.dingding.order.core.special.dao.ISpecialOrderDao;
import com.dingding.order.dto.pay.ReqOrderPayDTO;
import com.dingding.order.dto.pay.ResOrderPayDTO;

/**
 * @Description:专车支付订单业务类
 * @author fengshuonan
 * @date 2016年6月3日 上午11:46:11
 */
@Service("specialOrderPayService")
public class SpecialOrderPayServiceImpl extends AbstractResponse<ResOrderPayDTO, ReqOrderPayDTO>
		implements IOrderPayService {

	@Autowired
	private IOrderPayDao orderPayDao; // 订单支付dao

	@Autowired
	private ISpecialOrderDao specialOrderDao; // 专车订单支付dao

	@Resource(name = "userAccountService")
	private IUserAccountService userAccountService; // 用户账户service

	@Autowired
	private IQueueFacade queueFacade; // 队列服务

	@Resource(name = "baseDaoX")
	private IBaseDaoX baseDaoX;

	@Resource(name = "specialOrderService")
	private ISpecialOrderService specialOrderService;

	/**
	 * @Description: 订单支付
	 * @param requestJson 客户端请求JSON数据
	 * @author fengshuonan
	 * @return String 返回参数
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public String orderPay(String requestJson) {

		ReqOrderPayDTO orderPayReq = super.parseRequestJson(requestJson);

		// 验证参数是否为空
		ResponseEntity<ResOrderPayDTO> response = validateRequestPara(orderPayReq);

		if (response.getCode() != HttpStatus.SC_OK) {
			return super.responseBeanToJson(response);
		}

		// 执行订单支付，修改数据库中的信息
		response = changeOrderInfo(orderPayReq);

		if (response.getCode() != HttpStatus.SC_OK) {
			return super.responseBeanToJson(response);
		}

		// 封装返回状态
		response.setCode(HttpStatus.SC_OK);
		response.setErrorMessage("请求成功");

		return super.responseBeanToJson(response);
	}

	/**
	 * @Description: 验证请求参数是否正确
	 * @author fengshuonan
	 * @return boolean true 可用 false 不可用
	 */
	private ResponseEntity<ResOrderPayDTO> validateRequestPara(ReqOrderPayDTO orderPayReq) {

		ResponseEntity<ResOrderPayDTO> response = new ResponseEntity<ResOrderPayDTO>();

		if (orderPayReq == null) {
			response.setCode(OrderPayCodeMsg.ORDER_NOT_EXIST.getCode());
			response.setErrorMessage(OrderPayCodeMsg.ORDER_NOT_EXIST.getMessage());
			response.setPromptMessage(OrderPayCodeMsg.ORDER_NOT_EXIST.getMessage());
			return response;
		}

		ValiResult result = ValidateUtil.validateBeanIsAvaliable(orderPayReq, ReqOrderPayDTO.class);

		if (!result.isAvailable()) {
			response.setCode(OrderPayCodeMsg.PARA_DATA_NULL.getCode());
			response.setErrorMessage(result.getNullFieldName());
			response.setPromptMessage(OrderPayCodeMsg.PARA_DATA_NULL.getMessage());
		}

		return response;
	}

	/**
	 * @Description:执行乘客支付主流程
	 * @author fengshuonan
	 * @return void
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private ResponseEntity<ResOrderPayDTO> changeOrderInfo(ReqOrderPayDTO orderPayReq) {

		ResponseEntity<ResOrderPayDTO> response = new ResponseEntity<ResOrderPayDTO>();

		/**
		 * 获取订单信息
		 */
		UserspecialorderT order = null;
		String orderId = orderPayReq.getOid();
		// TODO 缓存获取订单

		if (order == null) {
			order = this.specialOrderDao.getById(orderId);
		}

		/**
		 * 验证订单是否合法(订单是否为空，用户余额是否足够)
		 */
		response = validateOrder(order, orderPayReq);
		if (response.getCode() != HttpStatus.SC_OK) {
			return response;
		}

		/**
		 * 更新订单信息
		 */
		this.updateOrderInfo(order, orderPayReq);

		/**
		 * 乘客扣款
		 */
		response = passengerCharge(order, orderPayReq);
		if (response.getCode() != HttpStatus.SC_OK) {
			return response;
		}

		return response;
	}

	/**
	 * @Title: getDriverId
	 * @Description: 根据订单信息和乘客Id获取司机Id
	 * @param userordert
	 *            订单信息
	 * @param passengerId
	 *            乘客Id
	 * @author yhq
	 * @return String 返回类型
	 * @throws
	 */
	public String getDriverId(UserspecialorderT order, String passengerId) {
		return order.getGrabOrderUserId();
	}

	/**
	 * @Description: 验证该订单是否可用
	 * @author fengshuonan
	 * @param orderPayReq
	 */
	private ResponseEntity<ResOrderPayDTO> validateOrder(UserspecialorderT order, ReqOrderPayDTO orderPayReq) {

		ResponseEntity<ResOrderPayDTO> response = new ResponseEntity<ResOrderPayDTO>();

		if (order == null) {
			response.setCode(OrderPayCodeMsg.PARA_DATA_NULL.getCode());
			response.setErrorMessage(OrderPayCodeMsg.PARA_DATA_NULL.getMessage());
			response.setPromptMessage(OrderPayCodeMsg.PARA_DATA_NULL.getMessage());
			return response;
		}

		if (order.getOrderStatus() == 0 && order.getOrderStatus() != 4) { // 不是待支付状态
			response.setCode(OrderPayCodeMsg.ORDER_STATUS_NOT_WAIT_PAY.getCode());
			response.setErrorMessage(OrderPayCodeMsg.ORDER_STATUS_NOT_WAIT_PAY.getMessage());
			response.setPromptMessage(OrderPayCodeMsg.ORDER_STATUS_NOT_WAIT_PAY.getMessage());
			return response;
		}

		/**
		 * 如果有叮币支付，验证账户余额是否够支付订单
		 */
		BigDecimal payMoney = orderPayReq.getPayMoney();
		if (payMoney != null && payMoney.compareTo(new BigDecimal(0)) > 0.0) {

			Useraccount useraccount = this.userAccountService.getUserAccount(orderPayReq.getPassengerID());
			BigDecimal remainMoney = useraccount.getCurrencyAmount();

			if (remainMoney == null || (remainMoney != null && remainMoney.compareTo(payMoney) < 0)) {
				response.setCode(OrderPayCodeMsg.USER_REMAIN_MONEY_NOT_ENOUGH.getCode());
				response.setErrorMessage(OrderPayCodeMsg.USER_REMAIN_MONEY_NOT_ENOUGH.getMessage());
				response.setPromptMessage(OrderPayCodeMsg.USER_REMAIN_MONEY_NOT_ENOUGH.getMessage());
				return response;
			}
		}

		return response;
	}

	/**
	 * @Description: 更新订单信息
	 * @author fengshuonan
	 * @return ResponseEntity<OrderPayResDTO>
	 */
	private void updateOrderInfo(UserspecialorderT order, ReqOrderPayDTO orderPayReq) {

		if (orderPayReq.getThirdPartyPayMoney() != null) {
			order.setAlipayMoney(orderPayReq.getThirdPartyPayMoney()); // 设置第三方支付金额
		}

		if (orderPayReq.getPayMoney() != null) {
			order.setPayMoney(orderPayReq.getPayMoney()); // 设置叮币支付金额
		}

		if (orderPayReq.getPayType() != null) { // 支付类型
			int type = orderPayReq.getPayType();
			order.setPayType(type);
		}

		BigDecimal thirdMoney = orderPayReq.getThirdPartyPayMoney() == null ? new BigDecimal(0) : orderPayReq.getThirdPartyPayMoney();
		BigDecimal dingMoney = orderPayReq.getPayMoney() == null ? new BigDecimal(0) : orderPayReq.getPayMoney();
		BigDecimal couponMoney = orderPayReq.getCouponMoney() == null ? new BigDecimal(0) : orderPayReq.getCouponMoney();

		order.setTotalMoney(thirdMoney.add(dingMoney).subtract(couponMoney)); // 设置总金额
	}

	/**
	 * @Description:乘客扣款操作
	 * @param order
	 *            订单
	 * @param orderPayReq
	 *            请求参数
	 * @author fengshuonan
	 * @return ResponseEntity<OrderPayResDTO>
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	private ResponseEntity<ResOrderPayDTO> passengerCharge(UserspecialorderT order, ReqOrderPayDTO orderPayReq) {

		ResponseEntity<ResOrderPayDTO> response = new ResponseEntity<ResOrderPayDTO>();
		ResOrderPayDTO orderPayResDTO = new ResOrderPayDTO();

		String userId = orderPayReq.getPassengerID();
		BigDecimal dingMoney = orderPayReq.getPayMoney();

		/**
		 * 根据付款类型进行相应的扣款工作
		 */
		if (orderPayReq.getThirdPartyPayMoney() == null || orderPayReq.getThirdPartyPayMoney().compareTo(new BigDecimal(0)) <= 0) {
			// 如果有叮币支付，扣除相应的账户余额
			if (dingMoney != null && dingMoney.compareTo(new BigDecimal(0)) >= 0.0) {
				if (userAccountService.deductRemainMoney(userId, dingMoney) == false) {
					response.setCode(OrderPayCodeMsg.DEDUCT_MONEY_FAIL.getCode());
					response.setErrorMessage(OrderPayCodeMsg.DEDUCT_MONEY_FAIL.getMessage());
					return response;
				}

				// 给司机转账
				if (!this.specialOrderService.orderPayNotify(order.getSpecialOrderId())) {
					response.setCode(OrderPayCodeMsg.DEDUCT_MONEY_FAIL.getCode());
					response.setErrorMessage(OrderPayCodeMsg.DEDUCT_MONEY_FAIL.getMessage());
					return response;
				}
			}
		}

		/**
		 * 如果有第三方支付，调用第三方支付api进行扣款
		 */
		if (orderPayReq.getPayType() == 1) { // 如果是支付宝支付
			// 等待第三方回调
		} else if (orderPayReq.getPayType() == 2) {// 如果是微信支付

			WechatPayOrderRequest orderRequest = WechatPayReqFactory.createRequest(WechatPayOrderRequest.class, 3);
			orderRequest.setWechatPayOrderRequest(orderPayReq.getOid(),
					orderPayReq.getThirdPartyPayMoney().multiply(new BigDecimal(100)).intValue(), orderPayReq.getIpAddress());

			String apiSec = "j5axbIfMSZjsiEGAScGMCUhp5kO2Oqaj";// API安全秘钥
			String stringSignTemp = ToolUtil.lexSortBean(orderRequest, WechatPayOrderRequest.class) + "key=" + apiSec;
			String sign = MD5Util.md5Encrypt(stringSignTemp).toUpperCase();
			orderRequest.setSign(sign);

			WechatPayApi api = new WechatPayApi();
			WechatPayOrderResponse orderResponse = api.placeAnOrder(orderRequest);

			// 如果微信下单没有成功
			if (orderResponse == null || (orderResponse.getReturn_code().equals("FAIL")
					|| orderResponse.getResult_code().equals("FAIL"))) {
				response.setCode(OrderPayCodeMsg.WEI_CHAT_PAY_FAIL.getCode());
				response.setErrorMessage(OrderPayCodeMsg.WEI_CHAT_PAY_FAIL.getMessage());
				return response;
			}

			// 根据返回结果进行二次签名
			SecondSign secondSign = WechatTool.getSecondSign(orderResponse.getPrepay_id(),
					orderResponse.getNonce_str());

			// 设置服务器的微信订单生成结果信息
			orderPayResDTO.setWechatOrder(secondSign.getPrepayid(), secondSign.getNoncestr(), secondSign.getTimestamp(),
					secondSign.getSign());
			response.setResponseBody(orderPayResDTO);

		} else if (orderPayReq.getPayType() == 3) {
			order.setOrderStatus(5);// 修改订单状态为已完成
			order.setPayTime(new Date());// 支付时间

			/**
			 * 推送以及发送短信
			 */
			// 获取司机Id
//			String driverId = this.getDriverId(order, orderPayReq.getPassengerID());

			// 乘客支付推送
//			pushAndSendMessage(orderPayReq.getPassengerID(), driverId, order);

			// 乘客支付通知
//			pushNotice(orderPayReq.getPassengerID(), driverId, order);
			
			/**
			 * 若果是纯叮币支付 加入到正式表
			 */
			Userspecialorder userspecialorder = new Userspecialorder();
			userspecialorder.setSpecialOrderId(order.getSpecialOrderId());
			userspecialorder.setIsComment(1);
			BeanUtils.copyProperties(order, userspecialorder);
			this.baseDaoX.save(userspecialorder);
			this.baseDaoX.delete(order);
		}

		orderPayResDTO.setOid(orderPayReq.getOid());
		orderPayResDTO.setThirdPartyPayMoney(orderPayReq.getThirdPartyPayMoney());
		response.setResponseBody(orderPayResDTO);

		return response;
	}

	/**
	 * @Description: 发送短信以及推送消息
	 * @author fengshuonan
	 * @return int 状态码（如果成功 返回0）
	 */
	public void pushAndSendMessage(String passengerId, String driverId, UserspecialorderT order) {

		Specialuserlogin login = this.orderPayDao.getSpecialUserLogin(driverId);

		SpecialOrderPayPushDto specialOrderPayPushDto = new SpecialOrderPayPushDto();
		specialOrderPayPushDto.setOid(order.getSpecialOrderId());
		specialOrderPayPushDto.setOrderStatus(order.getOrderStatus());
		specialOrderPayPushDto.setPublishType(3);

		// 创建推送Bean
		PushData pushData = new PushData();
		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("specialPaySuccessPush");
		// 推送内容
		pushData.setResponseBody(specialOrderPayPushDto);

		PushRequestDTO pushRequestDTO = new PushRequestDTO();
		pushRequestDTO.setAliasId(login.getAliasId());
		pushRequestDTO.setAlert(PushMsg.PASSENGER_PAY);
		pushRequestDTO.setRoleType(RoleType.Driver);
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));

		ClientType clientType = null;
		if (login.getClientType() == "iOS") { // iOS
			clientType = ClientType.iOS;
		} else { // Android
			clientType = ClientType.Android;
		}
		pushRequestDTO.setClientType(clientType);
		pushRequestDTO.setPushType(PushType.alert_msgcontent);

		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
	}

	/**
	 * 
	 * @Title: pushNotice 
	 * @Description: 乘客支付-推送通知
	 * @param pushBean 乘客支付推送内容
	 * @author YHQ 
	 * @since V2.3.2 
	 * @return void    返回类型
	 * 
	 */
	public void pushNotice(String passengerId, String driverId, UserspecialorderT order) {

		Specialuserlogin login = this.orderPayDao.getSpecialUserLogin(driverId);

		SpecialOrderPayPushDto specialOrderPayPushDto = new SpecialOrderPayPushDto();
		specialOrderPayPushDto.setOid(order.getSpecialOrderId());
		specialOrderPayPushDto.setOrderStatus(order.getOrderStatus());

		String content = "乘客已完成支付，请注意查收！";
		
		// 创建推送Bean
		PushData pushData = new PushData();
		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("newsNoticePush");
		// 确认到达推送内容
		pushData.setResponseBody(PushModel.noticeModel(1, content, null));

		PushRequestDTO pushRequestDTO = new PushRequestDTO();
		pushRequestDTO.setAliasId(login.getAliasId());
		pushRequestDTO.setAlert(PushMsg.PASSENGER_PAY);
		pushRequestDTO.setRoleType(RoleType.Driver);
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));

		ClientType clientType = null;
		if (login.getClientType() == "iOS") { // iOS
			clientType = ClientType.iOS;
		} else { // Android
			clientType = ClientType.Android;
		}
		pushRequestDTO.setClientType(clientType);
		pushRequestDTO.setPushType(PushType.msgcontent);

		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
	}

	@Override
	public String orderLinePay(String requestJson) {
		return null;
	}

}
